package serv_impl

import (
	"context"
	"sync"
	"time"

	"atomgit.com/openlinksaas/easy_net_proxy/config"
	"atomgit.com/openlinksaas/proto-gen-go.git/net_proxy_api"
	"github.com/google/uuid"
)

type TunnelItem struct {
	TunnelId     string
	EpCfg        *config.EndPointConfig
	LastReadTime int64
}

type NetProxyApiImpl struct {
	net_proxy_api.UnimplementedNetProxyApiServer
	cfg       *config.ServerConfig
	tunnelMap sync.Map
	connMap   sync.Map
}

func NewNetProxyApiImpl(cfg *config.ServerConfig) *NetProxyApiImpl {
	ret := &NetProxyApiImpl{
		cfg: cfg,
	}
	go func() {
		time.Sleep(1 * time.Minute)
		ret.cleanTunnel()
		ret.cleanConn()
	}()
	return ret
}

func (apiImpl *NetProxyApiImpl) ListEndPoint(ctx context.Context, req *net_proxy_api.ListEndPointRequest) (*net_proxy_api.ListEndPointResponse, error) {
	emptyList := []*net_proxy_api.EndPoint{}

	tokenInfo, err := apiImpl.getTokenInfo(apiImpl.cfg.LinkSaasAddr, req.Token)
	if err != nil {
		return &net_proxy_api.ListEndPointResponse{
			Code:         net_proxy_api.ListEndPointResponse_CODE_WRONG_TOKEN,
			ErrMsg:       "错误的访问令牌",
			EndPointList: emptyList,
		}, nil
	}
	if !apiImpl.hasPerm(tokenInfo.ProjectId, apiImpl.cfg.ProjectIdList) {
		return &net_proxy_api.ListEndPointResponse{
			Code:         net_proxy_api.ListEndPointResponse_CODE_NO_PERMISSION,
			ErrMsg:       "没有权限",
			EndPointList: emptyList,
		}, nil
	}

	endPointList := []*net_proxy_api.EndPoint{}
	for _, ep := range apiImpl.cfg.EndPointList {
		endPointList = append(endPointList, &net_proxy_api.EndPoint{
			EndPointId:   ep.Id,
			EndPointName: ep.Name,
		})
	}

	return &net_proxy_api.ListEndPointResponse{
		Code:         net_proxy_api.ListEndPointResponse_CODE_OK,
		EndPointList: endPointList,
	}, nil
}

func (apiImpl *NetProxyApiImpl) CreateTunnel(ctx context.Context, req *net_proxy_api.CreateTunnelRequest) (*net_proxy_api.CreateTunnelResponse, error) {
	tokenInfo, err := apiImpl.getTokenInfo(apiImpl.cfg.LinkSaasAddr, req.Token)
	if err != nil {
		return &net_proxy_api.CreateTunnelResponse{
			Code:   net_proxy_api.CreateTunnelResponse_CODE_WRONG_TOKEN,
			ErrMsg: "错误的访问令牌",
		}, nil
	}
	if !apiImpl.hasPerm(tokenInfo.ProjectId, apiImpl.cfg.ProjectIdList) {
		return &net_proxy_api.CreateTunnelResponse{
			Code:   net_proxy_api.CreateTunnelResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	var epCfg *config.EndPointConfig
	for _, ep := range apiImpl.cfg.EndPointList {
		if ep.Id == req.EndPointId && ep.Password == req.Password {
			epCfg = &ep
		}
	}
	if epCfg == nil {
		return &net_proxy_api.CreateTunnelResponse{
			Code:   net_proxy_api.CreateTunnelResponse_CODE_NO_ENDPOINT,
			ErrMsg: "连接端点不存在或密码错误",
		}, nil
	}

	nowTime := time.Now().Unix()
	tunnelId := uuid.NewString()
	apiImpl.tunnelMap.Store(tunnelId, &TunnelItem{
		TunnelId:     tunnelId,
		EpCfg:        epCfg,
		LastReadTime: nowTime,
	})

	return &net_proxy_api.CreateTunnelResponse{
		Code:     net_proxy_api.CreateTunnelResponse_CODE_OK,
		TunnelId: tunnelId,
	}, nil
}

func (apiImpl *NetProxyApiImpl) KeepTunnelAlive(ctx context.Context, req *net_proxy_api.KeepTunnelAliveRequest) (*net_proxy_api.KeepTunnelAliveResponse, error) {
	tunnelValue, ok := apiImpl.tunnelMap.Load(req.TunnelId)
	if !ok {
		return &net_proxy_api.KeepTunnelAliveResponse{
			Code:   net_proxy_api.KeepTunnelAliveResponse_CODE_NO_TUNNEL,
			ErrMsg: "通道不存在",
		}, nil
	}
	tunnelItem := tunnelValue.(*TunnelItem)
	tunnelItem.LastReadTime = time.Now().Unix()
	apiImpl.tunnelMap.Store(req.TunnelId, tunnelItem)

	return &net_proxy_api.KeepTunnelAliveResponse{
		Code: net_proxy_api.KeepTunnelAliveResponse_CODE_OK,
	}, nil
}
